package cn.bonoon.handler.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.transaction.Transactional;

import org.springframework.util.Assert;
import org.springframework.web.context.ServletContextAware;

import cn.bonoon.kernel.support.entities.Persistable;
import cn.bonoon.kernel.support.searcher.ISearcher;
import cn.bonoon.kernel.support.services.ServiceSupport;
import cn.bonoon.kernel.web.handlers.IExecutable;

/**
 * <pre>
 * 这是一个不太和谐的类，他介于业务逻辑层和控制器层之间；
 * 
 * 这个类专门处理自动加载数据，自动解析查询等方便，他即要有控制器层的一些属性，
 * 同又必须能直接访问数据库，并且同时需要开启数据库访问的事务。
 * </pre>
 * @author jackson
 *
 */
@Transactional
public class StandardAutoManager extends ServiceSupport implements ServletContextAware{

	protected ServletContext servletContext;

	protected final Map<String, IExecutable> handlers = new HashMap<String, IExecutable>();
	
	@Override
	public void setServletContext(ServletContext sc) {
		this.servletContext = sc;
	}
	
	@Override
	public void afterPropertiesSet() throws Exception { 
		Assert.notNull(servletContext, "这里应该要把servletContext加进来！");
	}
	
	/**
	 * <pre>
	 * 直接注册一个处理事件
	 * 
	 * 处理事件注册后，会返回一个该事件处理的请求的路径的后缀，
	 * 即当前请求再加上这个后缀，就是该事件的请求路径了；
	 * 
	 * 如：返回的后缀为<code>0!v.b</code>，当前的请求路径为<code>/u/user/{mid}</code>
	 * 则该处理事件的完整路径为<code>/u/user/{mid}/0!v.b</code>，该路径就是定义的事件的请求路径。
	 * </pre>
	 * <p>
	 * 注意：这里返回的是相对路径
	 * </p>
	 * <pre>
	 * 这里注册的处理器是Grid列表加载数据的处理器，默认提供的处理器有：
	 * 1.datagrid列表数据，不分页（{@link cn.bonoon.kernel.web.handlers.loader.ItemLoaderHandler ItemLoaderHandler}）
	 * 2.datagrid列表数据，分页（{@link cn.bonoon.kernel.web.handlers.loader.PageLoaderHandler PageLoaderHandler}）
	 * 3.treegrid列表数据，非ajax（{@link cn.bonoon.kernel.web.handlers.loader.NodeLoaderHandler NodeLoaderHandler}）
	 * 4.treegrid列表数据，ajax（{@link cn.bonoon.kernel.web.handlers.loader.AjaxNodeLoaderHandler AjaxNodeLoaderHandler}）
	 * </pre>
	 * @param handler
	 */
	public void register(IExecutable handler) {
		handlers.put(handler.getKey(), handler);
	}

	public ServletContext getServletContext() {
		return servletContext;
	}
	
	public ISearcher getSesrcher(Class<? extends Persistable> entityClass){
		return _register(entityClass);
	}
	
//	public StandardFinder buildeStandardFinder(){
//		return new StandardFinder(this);
//	}
//	
//	public ExtendFinder buildeExtendFinder(EntityReader reader, ReadEvent event){
//		return new ExtendFinder(reader, event, this);
//	}
	
	public List<?> query(String ql, Object arg){
		return entityManager.createQuery(ql.toString()).setParameter(1, arg).getResultList();
	}

	public IExecutable handler(String key) {
		return handlers.get(key);
	}
}
